//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using OpenLS.Chart.Internals;
using OpenLS.Core.Serialization;

namespace OpenLS.Chart
{
    public abstract class AreaChartBase : ChartBase, IDataLabelsOwner
    {
        private ObservableCollection<AreaSeries> _series;
        private DataLabels dlbls;
        private ChartLines dropLines;
        private Grouping grouping;
        private bool varyColors = true;
        public DataSource Categories
        {
            get
            {
                if (Series.Count == 0)
                    return null;
                AreaSeries firstSeries = Series[0];
                DataSource ds = firstSeries.Categories;
                if (ds == null)
                {
                    int count = GetDisplayInformation().Count;
                    return StringLiteral.NewStringLiteral(1, count);
                }
                return ds;
            }
        }


        public ChartLines DropLines
        {
            get { return dropLines; }
            set { dropLines = value; notifyPropertyChanged("DropLines");}
        }

        public DataLabels DataLabels
        {
            get { return dlbls; }
            set { dlbls = value; notifyPropertyChanged("DataLabels");}
        }

        public Grouping Grouping
        {
            get { return grouping; }
            set
            {
                grouping = value;
                notifyPropertyChanged("Grouping");
            }
        }

        public bool VaryColors
        {
            get { return varyColors; }
            set
            {
                varyColors = value;
                notifyPropertyChanged("VaryColors");
            }
        }

        public ObservableCollection<AreaSeries> Series
        {
            get
            {
                if (_series == null)
                {
                    _series = CreateSeriesCollection<AreaSeries>();
                    _series.CollectionChanged += delegate(object sender, NotifyCollectionChangedEventArgs args)
                    {
                        if (args.NewItems != null)
                            foreach (AreaSeries series in args.NewItems)
                                series.ValueChanged += OnSeriesChanged;
                        if (args.OldItems != null)
                            foreach (AreaSeries series in args.OldItems)
                                series.ValueChanged -= OnSeriesChanged;
                    };

                }
                return _series;
            }
        }
        private void OnSeriesChanged(object sender, EventArgs args)
        {
            notifyPropertyChanged("Categories");
        }


        #region IChartWithDisplayInformation Members

        #endregion

        protected void ReadXmlBase(ReadContext context)
        {
            Grouping = context.ReadOptionalElementEnumAttribute("grouping", Grouping.Standard);
            varyColors = ChartHelper.ReadVaryColors(context);
            Series.Clear();
            while (context.ReaderLocalName == "ser")
            {
                AreaSeries s = new AreaSeries();
                s.ReadXmlCore(context);
                Series.Add(s);
            }
            DataLabels = context.ReadOptionalElement<DataLabels>(DataLabels.xmlName);
            DropLines = context.ReadOptionalElementAs<ChartLines>("dropLines");
        }

        protected void WriteXmlBase(WriteContext context)
        {
            context.WriteOptionalElementEnumAttribute<Grouping>("grouping", Grouping); //\\change to non null
            ChartHelper.WriteVaryColors(context, VaryColors);
            foreach (AreaSeries s in Series)
                s.WriteXmlCore(context);
            context.WriteOptionalElement(DataLabels);
            context.WriteOptionalElementAs(DropLines, "dropLines");
        }

        internal INumericChartDisplayInformation GetDisplayInformation()
        {
            switch (Grouping)
            {
                case Grouping.Standard:
                    return new ClusteredDisplayInformation(Series);
                case Grouping.Stacked:
                    return new StackedDisplayInformation(Series);
                case Grouping.PercentStacked:
                    return new PercentStackedDisplayInformation(Series);
                default:
                    throw new NotSupportedException();
            }
        }
    }
}